package dk.itu.pam.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import dk.itu.pam.model.Basket;
import dk.itu.pam.model.Pizza;
import dk.itu.pam.model.User;
import dk.itu.pam.util.Parser;
import dk.itu.pam.util.PizzaMethods;
import dk.itu.pam.util.Validator;

/**
 * Servlet implementation class Controller
 */
public class Controller extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private static String SIGNUP_STATUS_JSP = "/signup_status.jsp";
	private static String EDIT_JSP = "/Edit.jsp";
	private static String SHOWALL_JSP = "/ShowAll.jsp";
	private static String ADMINPAGE_JSP = "/adminpage.jsp";
	private static String MAIL_JSP = "/mail.jsp";
	private static String ERRORPAGE_JSP = "/errorpage.jsp";
	private static String BROWSE_JSP = "/browse.jsp";
	private static String BROWSE_JSP_FIRST_PAGE = "/browse.jsp?page=0";
	private static String BASKET_JSP = "/basket.jsp";
	private static String HOME_JSP = "/home.jsp";
	private static String BILLED_JSP = "/billed.jsp";
	private static String SUBMITCODE_JSP = "/submit_code.jsp";
	
	

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public Controller() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		String forward = "";
		// Get a map of the request parameters
		@SuppressWarnings("unchecked")
		Map parameters = request.getParameterMap();
		if (parameters.containsKey("delete")) {
			forward = SIGNUP_STATUS_JSP;
		} else if (parameters.containsKey("edit")) {
			// forward = EDIT_JSP;
		} else {
			// forward = SHOWALL_JSP;
		}
		RequestDispatcher view = request.getRequestDispatcher(forward);
		view.forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		String forward = "";
		// Get a map of the request parameters
		@SuppressWarnings("unchecked")
		ServletContext c = getServletContext();
		HttpSession s = request.getSession();
		Map parameters = request.getParameterMap();
			
		if (parameters.containsKey("browse_add")) { // TO BE COPIE
			int id = Integer.parseInt(request.getParameter("browse_pizzaid"));
			//System.out.println("controller gets pizza id: " + id);
			
			ArrayList<Pizza> contextPizzas = (ArrayList<Pizza>) c.getAttribute("pizzas");
			
				Basket sessionBasket = (Basket) s.getAttribute("basket");
				if (sessionBasket != null) {
					ArrayList<Pizza> basketPizzas = sessionBasket.getPizzas();
					if (basketPizzas != null) {
						if (PizzaMethods.getPizzaArrayIndex(basketPizzas, id) < 0 ) {
							basketPizzas.add(contextPizzas.get(PizzaMethods.getPizzaArrayIndex(contextPizzas, id)));
						} else {
							HashMap<Integer, Integer> map = sessionBasket.getPizzaMap();
							int quantity;
							if(map.containsKey(id))	{
								quantity = (Integer) map.get(id);
								quantity++;
							}
							else quantity = 2;
							map.put(id, quantity);
							//basketPizzas.get(PizzaMethods.getPizzaArrayIndex(basketPizzas, id)).increementQuantities();
						}
					}
				}
			
			// add current page id as request parameter ?
			forward = BROWSE_JSP;
				
		} else if (parameters.containsKey("basket_remove")) { // TO BE COPIED
			int id = Integer.parseInt(request.getParameter("basket_pizzaid"));
			
				Basket sessionBasket = (Basket) s.getAttribute("basket");
				if (sessionBasket != null) {
					ArrayList<Pizza> basketPizzas = sessionBasket.getPizzas();
					if (basketPizzas != null) {
						HashMap<Integer, Integer> map = sessionBasket.getPizzaMap();
						if (map.containsKey(id)) {
							if((Integer) map.get(id)==2){
								map.remove(id);
							}
							else {
								int quantity = (Integer) map.get(id);
								quantity--;
								map.put(id, quantity);
							}
						}
						else{
							basketPizzas.remove(PizzaMethods.getPizzaArrayIndex(basketPizzas, id));
							}
					}
				}
						
			forward = BASKET_JSP;
			
		} else if(parameters.containsKey("basket_add")) {
			int id = Integer.parseInt(request.getParameter("basket_pizzaid"));
			Basket sessionBasket = (Basket) s.getAttribute("basket");
			HashMap<Integer, Integer> map = sessionBasket.getPizzaMap();
			int quantity;
			if(map.containsKey(id))	{
				quantity = (Integer) map.get(id);
				quantity++;
			}
			else quantity = 2;
			map.put(id, quantity);
			
			//ArrayList<Pizza> basketPizzas = sessionBasket.getPizzas();
			//basketPizzas.get(PizzaMethods.getPizzaArrayIndex(basketPizzas, id)).increementQuantities();
			
			forward = BASKET_JSP;
			
		} else if (parameters.containsKey("edit")) {
		
			// forward = EDIT_JSP;
			
		} else if (parameters.containsKey("signup_submit")){
			
			boolean errorFound = false;
			String error = "";
			
			String name = (String) request.getParameter("signup_name");
			System.out.println("navnet er" + name);
			if(name==""){
				errorFound = true;
				error += "You must enter a name \n";
			}
			
			String email = (String) request.getParameter("signup_mail");
			if(email==""){
				errorFound = true;
				error += "You must enter an e-mail address \n";
			}
				
			String address = (String) request.getParameter("signup_address");
			System.out.println(address);
			if(address==""){
				errorFound = true;
				error += "You must enter a delivery address \n";
			}
				
			String password = (String) request.getParameter("signup_password");
			if(!Validator.isPassword(password)){
				errorFound = true;
				error += "You must enter a valid password - it must contain at least six characters, at least one digit, at least one letter character, and at least one non-digit/letter-character \n";
			}
			
			String zip = (String) request.getParameter("signup_zip");
			if(!Validator.isZipCode(zip)){
				errorFound = true;
				error += "You must enter a delivery address \n";
			}
			
			String phone = (String) request.getParameter("signup_phone");
			if(!Validator.isPhoneNumber(phone)){
				errorFound = true;
				error += "You must enter an 8-digit telephone number \n";
			}
			
			if(errorFound){
				request.setAttribute("error", error);
				forward = ERRORPAGE_JSP;
			}
			else {
				//create new user and add to list of users
				User user = new User(name, email, password, address, Integer.parseInt(zip), Integer.parseInt(phone));
				ArrayList<User> users = (ArrayList<User>) c.getAttribute("users");
				users.add(user);
				c.setAttribute("users", users);
				s.setAttribute("currentUser", user);
				s.setAttribute("basket", new Basket());
				forward = MAIL_JSP;
			}
			
		} else if (parameters.containsKey("login_submit")) { 
			ArrayList<User> users = (ArrayList<User>) c.getAttribute("users");
			String userid = request.getParameter("login_userid");
			String password = request.getParameter("login_password");
			User u = null;
			
			if (users!=null){
				for (User uLoop : users){
					if (userid.equalsIgnoreCase(uLoop.getEmail()) 
							&& password.equalsIgnoreCase(uLoop.getPassword())){
						u = uLoop;
						if (s.getAttribute("currentUser")!=null){
							s.setAttribute("basket", new Basket());
						}
						s.setAttribute("currentUser", u);
						forward = HOME_JSP;
					}
				}
				if (u==null) {
					request.setAttribute("error", "You have not typed in a valid username and password!");
					forward = ERRORPAGE_JSP;
					}
			}
			else {
					request.setAttribute("error", "There is no users created");
					forward = ERRORPAGE_JSP;
					}
	
		} else if (parameters.containsKey("browse_minprice") || parameters.containsKey("browse_maxprice") ) {
			
			ArrayList<Pizza> contextPizzas = (ArrayList<Pizza>) c.getAttribute("pizzas");
			ArrayList<Pizza> sessionPizzas = (ArrayList<Pizza>) s.getAttribute("pizzas");
			List<Pizza> toBeRemoved = new ArrayList<Pizza>();
			List<Pizza> toBeAdded = new ArrayList<Pizza>();
			
			if (contextPizzas != null) {
				for (Pizza p: contextPizzas){
					toBeAdded.add(p.clone());
				}
			} else System.out.println("OMG IT IS NULL!");
			
			sessionPizzas = (ArrayList<Pizza>) toBeAdded;
			
			String minParameter = "";
			String maxParameter = "";
			
			String min = (String) request.getParameter("browse_minprice");
			if(min != null && min != "") {
				System.out.println("TEST " + sessionPizzas.size());
				Float minF = new Float(min);
				
				for (int i=0; i<sessionPizzas.size(); i++) {
					System.out.println("TEST2");
					System.out.println("min id: " + i);
					Pizza p = sessionPizzas.get(i);
					if (p.getPriceFloat() < minF) {
						toBeRemoved.add(p);
						System.out.println("remove min");
					}
				}
				s.setAttribute("min_price", min);
				minParameter = min;
			} else {
				s.removeAttribute("min_price");
			}
			
			String max = (String) request.getParameter("browse_maxprice");
			if(max != null && max != "") {
				Float maxF = new Float(max);
				
				for (int i=0; i<sessionPizzas.size(); i++) {
					System.out.println("max id: " + i);
					Pizza p = sessionPizzas.get(i);
					if (p.getPriceFloat() > maxF) {
						toBeRemoved.add(p);
						System.out.println("remove max");
					}
				}
				s.setAttribute("max_price", max);
				maxParameter = max;
			} else {
				s.removeAttribute("max_price");
			}
			
			sessionPizzas.removeAll(toBeRemoved);
			
			// GET PIZZAS FROM REMOTE WEB SERVICE WITHIN GIVEN PRICE RANGE
			sessionPizzas.addAll(Parser.getRemotePizzas(minParameter, maxParameter));
			
			s.setAttribute("pizzas", sessionPizzas);
			forward = BROWSE_JSP_FIRST_PAGE;
		}
		else if (parameters.containsKey("adminpage_remove")) { 
			
			ArrayList<Pizza> pizzaRemove = (ArrayList<Pizza>) c.getAttribute("pizzas");
			if (pizzaRemove != null) {
				int i = Integer.parseInt(request.getParameter("adminpage_pizzaid"));
				pizzaRemove.remove(i);
				System.out.println("remove(i): " + i);
				c.setAttribute("pizzas", pizzaRemove);
				forward = ADMINPAGE_JSP;
			}
			
			
		} else if (parameters.containsKey("adminpage_add")) { 
			ArrayList<Pizza> pizzaAdd = (ArrayList<Pizza>) c.getAttribute("pizzas");
			
			
			if (pizzaAdd == null) {
				System.out.println("pizzaAdd is null!");
				pizzaAdd = new ArrayList<Pizza>();
			}
			if (c.getAttribute("pizzaCount") == null) {
				System.out.println("pizzaCount is null!");
				c.setAttribute("pizzaCount", 0);
			}
			
			String pizza_name = request.getParameter("pizza_name");
			String pizza_toppings = request.getParameter("pizza_toppings");
			int pizza_count = (Integer) c.getAttribute("pizzaCount");
			pizza_count++;
			int pizza_price = -1;
			
			try {
				pizza_price = Integer.parseInt(request.getParameter("pizza_price"));		
			} catch (Exception e){
				System.out.println(e.getMessage());
			}
			if (pizza_price != -1){
				Pizza p = new Pizza(pizza_name,pizza_price, pizza_toppings, pizza_count);
				pizzaAdd.add(p);
				System.out.println("Adding new pizza: " + pizza_name );
				Collections.sort(pizzaAdd);
				c.setAttribute("pizzas", pizzaAdd);
				c.setAttribute("pizzaCount", pizza_count);
			}

			forward = ADMINPAGE_JSP;
		
		}
		else if(parameters.containsKey("checkout_yes")) {
			User check = (User) s.getAttribute("currentUser");
			if (check == null) {
				request.setAttribute("error", "Please log in before you can check out");
				forward = ERRORPAGE_JSP;
				}
			else if (!check.isValid()) {
				forward = SUBMITCODE_JSP;
			
			} else {
				forward = BILLED_JSP;
				}
			}
		
		else if(parameters.containsKey("checkout_no")) {
			forward = HOME_JSP;
		}
		
		else if(parameters.containsKey("submit_code_code")) {
			String enteredCode = (String) request.getParameter("code");
			String code = ("" + ((User) s.getAttribute("currentUser")).getEmail().hashCode()).substring(1,5);
			if(!enteredCode.equals(code)){
				String error = "You entered the wrong code. Please enter the 4-digit your received in the confirmation e-mail";
				request.setAttribute("error", error);
				forward = ERRORPAGE_JSP;
			}
			else {
				((User) s.getAttribute("currentUser")).setValid(true);
				forward = HOME_JSP;
			}
			
		}
		else {
			// forward = SHOWALL_JSP;
		}
		
		RequestDispatcher view = request.getRequestDispatcher(forward);
		view.forward(request, response);

	}

}
